package cn.yunyichina.provider.message.service.impl;

import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.message.AppMessageVo;
import cn.yunyichina.provider.iface.entity.message.SendSmsVo;
import cn.yunyichina.provider.message.dao.TextTemplateDao;
import cn.yunyichina.provider.message.entity.OrgAppTemplate;
import cn.yunyichina.provider.message.entity.TextTemplate;
import cn.yunyichina.provider.message.entity.TmpTemplate;
import cn.yunyichina.provider.message.entity.TmpTemplateList;
import cn.yunyichina.provider.message.utils.MsgAppUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.convert.ObjectParser;
import cn.yunyichina.utils.log.Log;
import cn.yunyichina.utils.log.constant.LogParamType;
import cn.yunyichina.utils.log.constant.LogScene;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest;
import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 短信发送
 * Created by Administrator on 2016/9/21.
 */
@Service
public class MsgSmsServiceImpl {
    private static Logger logger = LoggerFactory.getLogger(MsgSmsServiceImpl.class);

    private static String ALIDY_serverUrl = "http://gw.api.taobao.com/router/rest" ;//SystemConfig.getStringValue("ALIDY_serverUrl");
    private static String ALIDY_appKey= "23318487" ;//SystemConfig.getStringValue("ALIDY_appKey");
    //阿里大鱼发送短信Secret
    private static String ALIDY_appSecret= "3334ba567188504d874540cb6ba0154a";//SystemConfig.getStringValue("ALIDY_appSecret");
    private static String ALIDY_SignName="云医科技";//因为读取乱码，先写在程序中
    private static String BONE_SIGN_NAME="仁医骨科";//因为读取乱码，先写在程序中
    //阿里大鱼发送通用短信验证码模板ID
    private static String ALIDY_TemplateCode="SMS_7375182";//SystemConfig.getStringValue("ALIDY_TemplateCode")
    /**
     * 云医宝打印纸用光消息
     */
    private static String YUNYIBAO_PRINT_OUT_CODE="SMS_32460163";

    private static String BONE_EXPERT_FEEDBACK="SMS_67300747";//骨科平台 专家反馈通知
    private static String BONE_ORDER_CANCEL="SMS_67260752";//骨科平台 订单取消通知
    private static String BONE_ORDER_HANDLE_EXPERT="SMS_67295786";//骨科平台 订单处理通知（专家）
    private static String BONE_ORDER_HANDLE_DOCTOR="SMS_67170725";//骨科平台 订单处理通知（主治医生）
    private static String BONE_ADD_DOCTOR_SUCCESS="SMS_85940022";//骨科平台 新增医生成功
    private static String BONE_DIAGNOSE_DOCTOR_SUCCESS ="SMS_115120098";//骨科平台 面诊订单成功 医生成功
    private static String BONE_DIAGNOSE_USER_SUCCESS ="SMS_107715009"; //骨科平台 面诊订单支付成功 患者通知
    private static String STOP_REGISTER="SMS_57965281";//	挂号停诊消息
    private static String CHANGE_REGISTER="SMS_58045236";//挂号改诊通知
    private static String SCAN_PAY="SMS_58045236";//扫码付短信通知
    private static String SCAN_CLINIC_PAY_SUCCESS="SMS_68230170";//门诊缴费成功通知

    private static String CHECK_ACCOUNT_SUCCESS="SMS_78330026";//对账正常通知
    private static String CHECK_ACCOUNT_FAIL="SMS_67675308";//对账错误通知

//    private static String DRUG_NEW_ORDER="SMS_84045002";//处方外购订单通知

    private static  String SEEK_HELP_UNPAY ="SMS_120620017";//骨科平台 求助订单代缴费 患者通知
//    private static String DRUG_NEW_ORDER="SMS_84045002";//处方外购订单通知(变更为SMS_112935007)
    private static String DRUG_NEW_ORDER="SMS_112935007";//处方外购订单通知

    private  static String BONE_BED_SUBCRIBE_AWAIT ="SMS_122140035"; //骨科平台  床位预约 排队通知
    private  static String BONE_BED_SUBCRIBE_COMPLETE ="SMS_121955042";  //骨科平台  床位预约 住院通知
    private  static String BONE_BED_SUBCRIBE_REFUSE ="SMS_121895044";  //骨科平台  床位预约 拒绝取消通知
    private  static String BONE_ADMISSIONS_PAY ="SMS_125930060";//骨科平台 中欧高峰会 报名缴费通知
    @Autowired
    private MsgServiceImpl msgService;

    @Autowired
    private TextTemplateDao textTemplateDao;


    /**
     * 短信推送
     * 接口名称 yyt.message.msg.sms.send
     * @param data {to_user	接收人
    msg_type	消息类型
    msg_content	消息内容
    }
     * @return
     */
    public ResponseObject sendMsgSms(String data) {
        logger.info(data);
        ResponseObject response = new ResponseObject();

        JSONObject jsonObject = JsonUtils.parseObject(data);
        String mobile = (String) jsonObject.get("to_user");
        int msgType = 0;
        if(jsonObject.get("msg_type") instanceof String){
            msgType = ObjectParser.toInteger(jsonObject.get("msg_type"));
        }else if(jsonObject.get("msg_type") instanceof Integer){
            msgType = (int) jsonObject.get("msg_type");
        }
        Map<String,Object> msgContent;
        if(jsonObject.get("msg_content") instanceof String){
            msgContent = JsonUtils.parseObject(jsonObject.get("msg_content"),Map.class);
        }else {
            msgContent = (Map<String, Object>) jsonObject.get("msg_content");
        }

        //按模板发送消息的入参
        String templateCode = (String) jsonObject.get("template_code");
        String platformOrgAppCode = (String) jsonObject.get("platform_org_app_code");
        String orgCode = (String) jsonObject.get("org_code");


        TaobaoClient client = new DefaultTaobaoClient(ALIDY_serverUrl, ALIDY_appKey, ALIDY_appSecret);
        AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
        req.setExtend("123456");
        req.setSmsType("normal");
        req.setSmsFreeSignName(ALIDY_SignName);
        if(StringUtils.isBlank(templateCode)){

            switch (msgType) {
                case 1:
                    String code = (String) msgContent.get("code");
                    req.setSmsParamString("{\"code\":\"" + code + "\"}");
                    req.setSmsTemplateCode(ALIDY_TemplateCode);
                    break;
                case 3:
                    //云医宝打印纸用光消息
                    String hospitalName = (String) msgContent.get("hospital_name");
                    String machineCode = (String) msgContent.get("machine_code");
                    String paramString = "{\"hospitalName\":\"" + hospitalName
                            + "\",\"machineCode\":\"" + machineCode
                            + "\"}";
                    req.setSmsParamString(paramString);
                    req.setSmsTemplateCode(YUNYIBAO_PRINT_OUT_CODE);
                    break;
                case 51:
//                扫码付短信通知
                paramString =  "{\"receipt_num\":\"" + (String) msgContent.get("receipt_num")
                        + "\",\"his_message\":\""  + (String) msgContent.get("his_message")
                        + "\"}";
                req.setSmsParamString(paramString);
                req.setSmsTemplateCode(SCAN_CLINIC_PAY_SUCCESS);
                req.setSmsFreeSignName("智慧医院");
                break;
            case 90://骨科验证吗
                code = (String) msgContent.get("code");
                req.setSmsParamString("{\"code\":\"" + code + "\"}");
                req.setSmsTemplateCode(ALIDY_TemplateCode);
                req.setSmsFreeSignName(BONE_SIGN_NAME);
                break;
            case 200:
                /**
                 *对账正常通知
                 ${hospitalName}生成${date}（批次:${batch}）的对账数据正常,差错金额：${differenceAmount} 元，差错笔数：${differenceNumber}笔，可进入系统进行查看
                 */
                Map<String, String> map = new HashedMap();
                map.put("hospitalName", msgContent.get("hospital_name").toString());
                map.put("date", msgContent.get("date").toString());
                map.put("batch", msgContent.get("batch").toString());
                map.put("differenceAmount",msgContent.get("diff_amount").toString());
                map.put("differenceNumber",msgContent.get("diff_count").toString());
                req.setSmsParamString(JSON.toJSONString(map));
                req.setSmsTemplateCode(CHECK_ACCOUNT_SUCCESS);
                break;
            case 201:
                /**
                 * 对账错误通知
                 * ${hospitalName}生成${date}（批次:${batch}）的对账数据时发生${level}错误， 错误是:${problemDescription}。请联系管理员人工排查原因。
                 申请说明: 对账错误通知
                 */
                map = new HashedMap();
                map.put("hospitalName",msgContent.get("hospital_name").toString());
                map.put("date",msgContent.get("date").toString());
                map.put("batch",msgContent.get("batch").toString());
                map.put("level",msgContent.get("level").toString());
                map.put("problemDescription",msgContent.get("problem_description").toString());
                req.setSmsParamString(JSON.toJSONString(map));
                req.setSmsTemplateCode(CHECK_ACCOUNT_FAIL);
                break;
            case 91://专家反馈通知
                String userName = (String) msgContent.get("user_name");
                String orderTypeName = (String) msgContent.get("order_type_name");
                paramString =  "{\"userName\":\"" + userName
                        + "\",\"orderTypeName\":\""  + orderTypeName
                        + "\"}";
                req.setSmsParamString(paramString);
                req.setSmsTemplateCode(BONE_EXPERT_FEEDBACK);
                req.setSmsFreeSignName(BONE_SIGN_NAME);
                break;
            case 92://订单取消通知
                userName = (String) msgContent.get("user_name");
                orderTypeName = (String) msgContent.get("order_type_name");
                paramString =  "{\"userName\":\"" + userName
                        + "\",\"orderTypeName\":\""  + orderTypeName
                        + "\"}";
                req.setSmsParamString(paramString);
                req.setSmsTemplateCode(BONE_ORDER_CANCEL);
                req.setSmsFreeSignName(BONE_SIGN_NAME);
                break;
            case 93://订单处理通知（专家）
                String doctorName = (String) msgContent.get("doctor_name");
                userName = (String) msgContent.get("user_name");
                orderTypeName = (String) msgContent.get("order_type_name");
                paramString =  "{\"doctorName\":\"" + doctorName
                        + "\",\"userName\":\""  + userName
                        + "\",\"orderTypeName\":\""  + orderTypeName
                        + "\"}";
                req.setSmsParamString(paramString);
                req.setSmsTemplateCode(BONE_ORDER_HANDLE_EXPERT);
                req.setSmsFreeSignName(BONE_SIGN_NAME);
                break;
            case 94://订单处理通知（专家）
                doctorName = (String) msgContent.get("doctor_name");
                userName = (String) msgContent.get("user_name");
                orderTypeName = (String) msgContent.get("order_type_name");
                paramString =  "{\"doctorName\":\"" + doctorName
                        + "\",\"userName\":\""  + userName
                        + "\",\"orderTypeName\":\""  + orderTypeName
                        + "\"}";
                req.setSmsParamString(paramString);
                req.setSmsTemplateCode(BONE_ORDER_HANDLE_DOCTOR);
                req.setSmsFreeSignName(BONE_SIGN_NAME);
                break;
            case 95://新增医生（专家）成功通知
                doctorName = (String) msgContent.get("doctor_name");
                String password = (String) msgContent.get("password");
                String connect = (String) msgContent.get("connect");
                paramString =  "{\"doctorName\":\"" + doctorName
                        + "\",\"password\":\""  + password
                        + "\",\"connect\":\""  + connect
                        + "\"}";
                req.setSmsParamString(paramString);
                req.setSmsTemplateCode(BONE_ADD_DOCTOR_SUCCESS);
                req.setSmsFreeSignName(BONE_SIGN_NAME);
                break;
            case 96://面诊订单（患者）支付成功通知
                paramString =  "{\"doctorName\":\"" + msgContent.get("doctor_name")
                        + "\",\"userName\":\""  + msgContent.get("user_name")
                        + "\",\"scheduleTime\":\""  + msgContent.get("schedule_time")
                        + "\",\"address\":\""  + msgContent.get("address")
                        + "\",\"reserveNo\":\""  + msgContent.get("reserve_no")
                         + "\"}";
                req.setSmsParamString(paramString);
                req.setSmsTemplateCode(BONE_DIAGNOSE_USER_SUCCESS);
                req.setSmsFreeSignName(BONE_SIGN_NAME);
                break;
            case 97://面诊订单（医生）支付成功通知
                paramString =  "{\"doctorName\":\"" + msgContent.get("doctor_name")
                        + "\",\"userName\":\""  + msgContent.get("user_name")
                        + "\",\"scheduleTime\":\""  + msgContent.get("schedule_time")
                        + "\",\"address\":\""  + msgContent.get("address")
                        + "\"}";
                req.setSmsParamString(paramString);
                req.setSmsTemplateCode(BONE_DIAGNOSE_DOCTOR_SUCCESS);
                req.setSmsFreeSignName(BONE_SIGN_NAME);
                break;
                case 98://求助订单 待缴费通知
                    paramString =  "{\"userName\":\"" + msgContent.get("user_name")
                            + "\"}";
                    req.setSmsParamString(paramString);
                    req.setSmsTemplateCode(SEEK_HELP_UNPAY);
                    req.setSmsFreeSignName(BONE_SIGN_NAME);
                    break;
                case 99: //中欧高峰会报名缴费通知
                    paramString =  "{\"fullName\":\"" + msgContent.get("user_name")
                            + "\"}";
                    req.setSmsParamString(paramString);
                    req.setSmsTemplateCode(BONE_ADMISSIONS_PAY);
                    req.setSmsFreeSignName(BONE_SIGN_NAME);
                    break;
                case 101: //床位预约 排队
                    paramString =  "{\"doctorName\":\"" + msgContent.get("doctor_name")
                            + "\",\"userName\":\""  + msgContent.get("user_name")
                            + "\"}";
                    req.setSmsParamString(paramString);
                    req.setSmsTemplateCode(BONE_BED_SUBCRIBE_AWAIT);
                    req.setSmsFreeSignName(BONE_SIGN_NAME);
                    break;
                case 102: //床位预约 通知住院
                    paramString =  "{\"userName\":\"" + msgContent.get("user_name")
                            + "\",\"InHospitalSite\":\""  + msgContent.get("in_hospital_site")
                            + "\",\"InHospitalTime\":\""  + msgContent.get("in_hospital_time")
                            + "\"}";
                    req.setSmsParamString(paramString);
                    req.setSmsTemplateCode(BONE_BED_SUBCRIBE_COMPLETE);
                    req.setSmsFreeSignName(BONE_SIGN_NAME);
                    break;
                case 103: //床位预约 拒绝预约
                    paramString =  "{\"userName\":\"" + msgContent.get("user_name")
                            + "\",\"doctorName\":\""  + msgContent.get("doctor_name")
                            + "\",\"cancleReason\":\""  + msgContent.get("cancle_reason")
                            + "\"}";
                    req.setSmsParamString(paramString);
                    req.setSmsTemplateCode(BONE_BED_SUBCRIBE_REFUSE);
                    req.setSmsFreeSignName(BONE_SIGN_NAME);
                    break;
            case 61://挂号停诊
                Map<String,String> param = new HashedMap();
                param.put("hospitalName", (String) msgContent.get("hospital_name"));
                param.put("userName",(String) msgContent.get("user_name"));
                param.put("deptName",(String) msgContent.get("dept_name"));
                param.put("doctorName",(String) msgContent.get("doctor_name"));
                param.put("scheduleDateLable",(String) msgContent.get("schedule_date"));

                req.setSmsParamString(com.alibaba.fastjson.JSON.toJSONString(param));
                req.setSmsTemplateCode(STOP_REGISTER);
                break;
            case 62://改诊
                param = new HashedMap();
                param.put("hospitalName", (String) msgContent.get("hospital_name"));
                param.put("userName",(String) msgContent.get("user_name"));
                param.put("deptName",(String) msgContent.get("dept_name"));
                param.put("doctorName",(String) msgContent.get("doctor_name"));
                param.put("scheduleDateLable",(String) msgContent.get("schedule_date"));

                req.setSmsParamString(com.alibaba.fastjson.JSON.toJSONString(param));
                req.setSmsTemplateCode(CHANGE_REGISTER);
                break;
            case 23900://处方外购订单通知
                param = new HashedMap();
                param.put("store_name", (String) msgContent.get("store_name"));
                req.setSmsParamString(com.alibaba.fastjson.JSON.toJSONString(param));
                req.setSmsTemplateCode(DRUG_NEW_ORDER);
                break;
            default:
                response.setResultCodeAndMessage("70001", "消息类型不正确");
                break;

            }
        }else{
            //按模板发送消息
            OrgAppTemplate orgAppTemplate = new OrgAppTemplate();
            orgAppTemplate.setPlatformOrgAppCode(platformOrgAppCode);
            orgAppTemplate.setDevOrgCode(platformOrgAppCode);
            TmpTemplate tmpTemplate = msgService.getTmpTemplate(templateCode,platformOrgAppCode,orgCode,4);
            if(tmpTemplate == null){
                response.setResultCodeAndMessage("","模板编号不存在：" + templateCode);
                return response;
            }
            List<TmpTemplateList> tmpTemplatelist = tmpTemplate.getListTmpTemplateList();
            if (tmpTemplatelist != null && tmpTemplatelist.size() > 0) {
                Map<String,Object> dayuParam = new HashedMap();
                for (TmpTemplateList node : tmpTemplatelist) {
                    String value = node.getValue();
                    value = value == null ? "" : value;


                    JSONObject newNode = new JSONObject();
                    newNode.put("node", node.getNode());
                    newNode.put("font_color", node.getFontColour());

                    newNode.put("value",value);

                    dayuParam.put(node.getNode(),msgContent.get(node.getKeyword()) == null?"":msgContent.get(node.getKeyword()));

                }
                req.setSmsParamString(com.alibaba.fastjson.JSON.toJSONString(dayuParam));
                req.setSmsTemplateCode(tmpTemplate.getPayTemplateId());
            }
        }

        req.setRecNum(mobile);

        try {
            AlibabaAliqinFcSmsNumSendResponse rsp = client.execute(req);
            logger.info("sendMsgSms 调用阿里大鱼发送短信返回:" + JsonUtils.toJsonString(rsp));
            if(rsp.getErrorCode()==null){
                response.setResultCodeAndMessage("0", "成功");
            }else{
                response.setResultCodeAndMessage(rsp.getErrorCode(),  rsp.getSubMsg());
            }
        } catch (ApiException e) {
            response.setResultCodeAndMessage("8000", "调用阿里大鱼发送短信出现了异常");
            logger.error("调用阿里大鱼发送短信出现了异常！", e);
        }

        return response;
    }



    /**
     * 短信推送重构接口
     * @param sendSmsVo
     * @interfaceName: yyt.message.msg.sms.god.send
     * @return
     */
    public ResponseObject sendMsgSmsGod(SendSmsVo sendSmsVo) {
        Log.i(LogScene.MSG,"yyt.message.msg.sms.god.send", LogParamType.REQUEST,sendSmsVo.getMobileNo(), JsonUtils.toJsonString(sendSmsVo));
        ResponseObject response = new ResponseObject();

        AppMessageVo appMessageVo = new AppMessageVo();
        appMessageVo.setPlatformOrgAppCode(sendSmsVo.getPlatformOrgAppCode());
        appMessageVo.setDevOrgCode(sendSmsVo.getOrgCode());
        appMessageVo.setPlatformType((short) 4);
        appMessageVo.setLibraryTemplateType((short) 1);
        appMessageVo.setPlatformTemplateCode(sendSmsVo.getTemplateCode());
        appMessageVo.setMsgContentMap(sendSmsVo.getMsgContentMap());
        OrgAppTemplate orgAppTemplat = MsgAppUtils.getOrgAppTemplat(JsonUtils.toJsonString(appMessageVo));
        if(orgAppTemplat != null){
            //获取推送文本表信息
            TextTemplate textTemplate = new TextTemplate();
            textTemplate.setTemplateCode(orgAppTemplat.getLibraryTemplateCode());
            textTemplate.setPlatformType(orgAppTemplat.getPlatformType());
            List<TextTemplate> tmpTemplates = textTemplateDao.select(textTemplate);
            if(tmpTemplates.size() < 1){
                Log.i(LogScene.MSG_TXT,"yyt.message.msg.sms.god.send", LogParamType.NORMAL,sendSmsVo.getMobileNo(),"获取ImageTemplate失败：" + JsonUtils.toJsonString(textTemplate));
                response.setResultCodeAndMessage("8301" , "获取ImageTemplate失败：" + JsonUtils.toJsonString(textTemplate));
            }
            textTemplate = tmpTemplates.get(0);

            Log.i(LogScene.MSG_TXT,"yyt.message.msg.sms.god.send", LogParamType.NORMAL,sendSmsVo.getMobileNo(),"成功获取ImageTemplate内容：" + JsonUtils.toJsonString(textTemplate));

            //构造体返回
            appMessageVo.setMsgContentMap(sendSmsVo.getMsgContentMap());
            try {
//                String paramString = MsgAppUtils.getResultTextMsgContentStr(textTemplate, appMessageVo);
                String paramString = JSON.toJSONString(sendSmsVo.getMsgContentMap());
                AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
                req.setExtend("interfaceName: sendMsgSmsGod");
                req.setSmsType("normal");
                req.setSmsFreeSignName(sendSmsVo.getSmsSignName().getName());
                req.setSmsTemplateCode(sendSmsVo.getSmsCode().getCode());
                req.setSmsParamString(paramString);
                req.setRecNum(sendSmsVo.getMobileNo());

                //执行发送阿里大鱼短信消息
                try {
                    TaobaoClient client = new DefaultTaobaoClient(ALIDY_serverUrl, ALIDY_appKey, ALIDY_appSecret);
                    AlibabaAliqinFcSmsNumSendResponse rsp = client.execute(req);
                    Log.i(LogScene.MSG_TXT,"yyt.message.msg.sms.god.send", LogParamType.NORMAL,sendSmsVo.getMobileNo(),"sendMsgSms 调用阿里大鱼发送短信返回:" + JsonUtils.toJsonString(rsp));
                    if(rsp.getErrorCode()==null){
                        response.setResultCodeAndMessage("0", "成功");
                    }else{
                        response.setResultCodeAndMessage(rsp.getErrorCode(),  rsp.getSubMsg());
                    }
                } catch (ApiException e) {
                    response.setResultCodeAndMessage("8302", "调用阿里大鱼发送短信出现了异常");
                    Log.e(LogScene.MSG_TXT,"MsgSmsServiceImpl.sendMsgSmsGod 调用阿里大鱼发送短信出现了异常！" ,e);
                }

            } catch (Exception e) {
                Log.e(LogScene.MSG_TXT,"MsgSmsServiceImpl.sendMsgSmsGod 执行构造参数体方法异常！" ,e);
            }

        }else {
            Log.i(LogScene.MSG,"yyt.message.msg.sms.god.send", LogParamType.NORMAL,sendSmsVo.getMobileNo(), "获取orgAppTemplat为空");
            response.setResultCodeAndMessage(Response.FAILURE_CODE , Response.FAILURE_MESSAGE);
        }

        return response;
    }

}
